(function() {
	var app = angular.module('projectRtc', [],
		function($locationProvider) {
			$locationProvider.html5Mode(true);
		}
	);
	var client = new PeerManager();
	var mediaConfig = {
		audio: true,
		video: {
			mandatory: {},
			optional: []
		}
	};
	var callId;

	app.factory('camera', ['$rootScope', '$window',
		function($rootScope, $window) {
			var camera = {};
			camera.preview = $window.document.getElementById('localVideo');

			camera.start = function() {
				var remoteChange = arguments[0];

				return requestUserMedia(mediaConfig)
					.then(function(stream) {
						var oldCamera = camera.stream;

						attachMediaStream(camera.preview, stream);
						client.setLocalStream(stream);
						camera.stream = stream;
						$rootScope.$broadcast('cameraIsOn', true);

						if (remoteChange) {
							try {
								if (callId) {
									client.switchStream(callId);
									if (oldCamera) {
										setTimeout(function() {
											oldCamera.stop();
										}, 600);
									}
								}
							} catch (e) {
								console.log('切换流到远程失败');
							}
						}


					})
					.catch(Error('Failed to get access to local media.'));
			};
			camera.stop = function() {
				return new Promise(function(resolve, reject) {
						try {
							camera.stream.stop();
							camera.preview.src = '';
							resolve();
						} catch (error) {
							reject(error);
						}
					})
					.then(function(result) {
						$rootScope.$broadcast('cameraIsOn', false);
					});
			};
			return camera;
		}
	]);

	app.controller('RemoteStreamsController', ['camera', '$location', '$http',
		function(camera, $location, $http) {
			var rtc = this;
			rtc.remoteStreams = [];

			function getStreamById(id) {
				for (var i = 0; i < rtc.remoteStreams.length; i++) {
					if (rtc.remoteStreams[i].id === id) {
						return rtc.remoteStreams[i];
					}
				}
			}
			rtc.loadData = function() {
				// get list of streams from the server
				$http.get('/streams.json').success(function(data) {
					// filter own stream
					var streams = data.filter(function(stream) {
						return stream.id != client.getId();
					});
					// get former state
					for (var i = 0; i < streams.length; i++) {
						var stream = getStreamById(streams[i].id);
						streams[i].isPlaying = (!!stream) ? stream.isPLaying : false;
					}
					// save new streams
					rtc.remoteStreams = streams;
				});
			};

			rtc.view = function(stream) {
				client.peerInit(stream.id);
				stream.isPlaying = !stream.isPlaying;
			};
			rtc.call = function(stream) {
				/* If json isn't loaded yet, construct a new stream 
				 * This happens when you load <serverUrl>/<socketId> :
				 * it calls socketId immediatly.
				 **/

				function playremote() {
					if (!stream.isPlaying) {
						client.toggleLocalStream(stream.id);
						if (stream.isPlaying) {
							client.peerRenegociate(stream.id);
						} else {
							client.peerInit(stream.id);
						}
						stream.isPlaying = !stream.isPlaying;
					}
				}

				if (!stream.id) {
					stream = {
						id: stream,
						isPlaying: false
					};
					rtc.remoteStreams.push(stream);
				}
				if (camera.isOn) {
					client.toggleLocalStream(stream.id);
					if (stream.isPlaying) {
						client.peerRenegociate(stream.id);
					} else {
						client.peerInit(stream.id);
					}
					stream.isPlaying = !stream.isPlaying;
				} else {
					camera.start()
						.then(function(result) {
							playremote();
						})
						.catch(function(err) {
							console.log(err);
							try {
								playremote();
							} catch (e) {
								console.log(e)
							}
						});
				}
			};

			//initial load
			rtc.loadData();
			var url = $location.url();
			if (url != '/') {
				var arr = url.split('/');
				callId = arr[arr.length - 1];
				rtc.call(callId);
			};
		}
	]);

	app.controller('LocalStreamController', ['camera', '$scope', '$window',
		function(camera, $scope, $window) {
			var localStream = this;
			localStream.name = '3D_Desktop_'+parseInt(''+Math.random()*10);
			localStream.link = '';
			localStream.cameraIsOn = false;

			$scope.$on('cameraIsOn', function(event, data) {
				$scope.$apply(function() {
					localStream.cameraIsOn = data;
				});
			});

			localStream.toggleCam = function() {
				if (localStream.cameraIsOn) {
					camera.stop()
						.then(function(result) {
							client.send('leave');
							client.setLocalStream(null);
						})
						.catch(function(err) {
							console.log(err);
						});
				} else {
					camera.start()
						.then(function(result) {
							localStream.link = $window.location.host + '/' + client.getId();
							client.send('readyToStream', {
								name: localStream.name
							});
						})
						.catch(function(err) {
							console.log(err);
						});
				}
			};


			//根据ID初始化界面和事件
			function initSource(id) {
				var v = document.getElementById(id);

				if (v.style.display == 'none' || v.style.display == '') {
					v.style.display = 'block';
					v.onclick = clickBtn;
				}

			}

			function clickBtn(e) {
				var target = document.getElementById(e.target.attributes.target.value);
				//隐藏其他
				var lists = document.getElementsByClassName('source-list');
				for (var i = 0; i < lists.length; i++) {
					var _i = lists[i];
					if (_i != target) {
						_i.style.display = 'none';
					}
				}
				//显示目标
				if (target.style.display == 'none' || target.style.display == '') {
					target.style.display = 'block';
				}
			}

			function initHtml(videoList, audioList) {
				if (audioList.length > 0) {
					var btn = document.getElementById('sourceAudio');
					btn.style.display = 'block';

					var list = document.getElementById('sourceAudioList');
					list.innerHTML = '<button class="cancel">关闭</button><ul>' + audioList.join('') + '</ul>';
				} else {
					console.log('没有音频设备');
				}
				if (videoList.length > 0) {
					var btn = document.getElementById('sourceVideo');
					btn.style.display = 'block';

					var list = document.getElementById('sourceVideoList');
					list.innerHTML = '<button class="cancel">关闭</button><ul>' + videoList.join('') + '</ul>';
				} else {
					console.log('没有视频设备');
				}
			}

			function initEvent() {
				var options = document.getElementById('sourceOption');
				options.onmouseover = function() {
					options.style.opacity = 1;
				};
				options.onmouseout = function() {
					options.style.opacity = 0.3;
				}

				//关闭事件
				var cancels = document.getElementsByClassName('cancel');
				for (var i = 0; i < cancels.length; i++) {
					var c = cancels[i];
					c.onclick = function(e) {
						var target = e.target.parentNode;
						target.style.display = 'none';
					}
				}
				//切换事件
				var items = document.getElementsByClassName('sourceItem');
				for (var i = 0; i < items.length; i++) {
					var item = items[i];
					item.onclick = function(e) {
						var _this = e.target;
						var type = _this.attributes.name.value;
						var id = _this.value;
						console.log("切换:" + type + ",id : " + id);
						if (type == 'video') {
							mediaConfig.video = {
								optional: [{
									sourceId: id
								}]
							};
						} else if (type == 'audio') {
							mediaConfig.audio = {
								optional: [{
									sourceId: id
								}]
							}
						}
						camera.start(true);
					}
				}

			}

			//获取选择项
			function gotSources(sourceInfos) {


				var videoList = [],
					audioList = [];

				for (var i = 0; i !== sourceInfos.length; ++i) {
					var sourceInfo = sourceInfos[i];
					if (sourceInfo.kind === 'audio') {
						initSource('sourceAudio');
						var txt = sourceInfo.label || '音频' + (audioList.length + 1);
						audioList.push('<li><input class="sourceItem" type="radio" ' + (audioList.length == 0 ? 'checked="true"' : '') + ' name="audio" value="' + sourceInfo.id + '" >' + txt + '</li>');
					} else if (sourceInfo.kind === 'video') {
						initSource('sourceVideo');
						var txt = sourceInfo.label || '视频' + (videoList.length + 1);
						videoList.push('<li><input class="sourceItem" type="radio" ' + (videoList.length == 0 ? 'checked="true"' : '') + ' name="video" value="' + sourceInfo.id + '" >' + txt + '</li>');
					}
				}

				initHtml(videoList, audioList);
				initEvent();
			}
			//判断是否支持输入源
			if (typeof MediaStreamTrack === 'undefined') {
				try {
					console.log('浏览器不支持选择输入源');
				} catch (e) {}
			} else {
				//如果有选择源的界面
				setTimeout(function() {
					var box = document.getElementById('sourceOption');
					if (box) {
						MediaStreamTrack.getSources(gotSources);
					}
				}, 300);

			}
		}
	]);
})();